/** 
 * @addtogroup hft
 * hft
 * @brief 查询子命令处理
 * 
 * 本文件接口提供了下线检测协议查询命令的解码接口以及应答消息的编码接口。
 * 
 * @code{c}
 * THftCmdQuery g_query_;
 * THftUserData g_user_data_;
 * 
 * // 查询终端ID处理
 * Int32 THftCmdQueryDevId(void *sender, THtpQueryAckBody *ack_body)
 * {
 *     Int32 result = 0;
 * 
 *     ack_body->ack_result = PdkGetDevId(); //如果有读取失败，需要判断
 * 
 *     return reuslt;
 * }
 * 
 * // 查询终端工作模式处理
 * Int32 THftCmdQueryDevMode(void *sender, THtpQueryAckBody *ack_body)
 * {
 *     Int32 result = 0;
 * 
 *     ack_body->ack_result = PdkGetDevMode(); //如果有读取失败，需要判断
 * 
 *     return reuslt;
 * }
 * 
 * // 查询终端列表
 * THftCmdQueryServiceType service_tbl[] = 
 * {
 *     {kHtpQueryDevId,    &g_user_data_, THftCmdQueryDevId},
 *     {kHtpQueryDevMode,  &g_user_data_, THftCmdQueryDevMode},
 * }
 * 
 * // 创建查询功能
 * THftCmdQueryCreate(&g_query_, service_tbl, 2);
 * 
 * // 解析出查询消息
 * THtpMsg msg; // 假设此消息已经争取解析出来
 * HtpFrameDecode(src_buf, buf_len, &msg, &pop_size);
 * // ....
 * 
 * // 处理查询消息
 * Int32 result;
 * UInt8   dest_buf[1024];
 * result = THftCmdQueryProc(&g_query_, &msg, dest_buf, sizeof(dest_buf));
 * if (result > 0)
 *      ;// 发送成功应答
 * else
 *      ;// 处理失败应答
 * 
 * @endcode
 * 
 * @{
 *
 * @file         hft_cmd_query.h
 * @brief        查询子命令处理
 * @note    
 * @author       lixinliang
 * @date         2020-01-2
 * @version      1.0
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version          <th>Author                     <th>Description
 * <tr><td>2020-01-21  <td>1.0              <td>lixinliang@hopechart.com   <td>创建初始版本
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */

#ifndef _HFT_CMD_QUERY_H_
#define _HFT_CMD_QUERY_H_

#include "ofc/ofc_types.h"
#include "ofc/ofc_object.h"
#include "hft/hft_proto.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 查询命令执行函数
 * @param sender: 用户对象 有些检测场景，需要有用户的上下文
 * @param ack_body: 应答消息体 用户填充内容
 * @return 0:成功 -1:失败
 */
typedef Int32 (*THftCmdQueryFunc)(void *sender, THtpQueryAckBody *ack_body); 

/**
 * 查询服务数据项
 */
typedef struct THftCmdQueryServiceTypeTag THftCmdQueryServiceType;
struct THftCmdQueryServiceTypeTag
{
    THtpCmdQueryType query_id; ///< 查询ID
    void             *sender;  ///< 用户自有属性
    THftCmdQueryFunc Method;   ///< 处理方法
};

/**
 * 构造函数
 * @param self: 对象指针 
 * @return 
 */
typedef struct THftCmdQueryTag THftCmdQuery;
struct THftCmdQueryTag
{
PRIVATE
    THftCmdQueryServiceType *svr_table; ///< 服务列表
    UInt32                  table_size; ///< 列表长度
};

/**
 * 构造函数
 * @param self: 对象指针 
 * @param table: 支持的服务列表 
 * @param size: 服务列表项数 
 * @return 
 */
Bool THftCmdQueryCreate(THftCmdQuery *self, THftCmdQueryServiceType table[], UInt32 size);

/**
 * 查询是否支持自服务
 * @param self: 对象指针 
 * @param query_id: 查询服务ID 
 * @return >=0: 服务项索引 <0:不支持
 */
Int32 THftCmdQuerySupportSubService(THftCmdQuery *self, THtpCmdQueryType query_id);

/**
 * 命令处理函数
 * @param self: 对象指针
 * @param msg: 已知消息
 * @param dst_buf: 响应缓存
 * @param buf_size: 响应缓存长度
 * @return <0：执行失败返回码 >0:执行成功，响应的数据长度
 */
Int32 THftCmdQueryProc(THftCmdQuery *self, const THtpMsg *msg, Byte *dest_buf, Int32 buf_size);

/**
 * 析构函数
 * @param self: 对象指针
 * @return 
 */
void THftCmdQueryDestroy(THftCmdQuery *self);

#ifdef __cplusplus
}
#endif

#endif // _HFT_CMD_QUERY_H_
/** @} */
